<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- 
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License. 
-->
<html>
<head>
    <link type="text/css" rel="stylesheet" href="https://struts.apache.org/css/default.css">
    <style type="text/css">
        .dp-highlighter {
            width:95% !important;
        }
    </style>
    <style type="text/css">
        .footer {
            background-image:      url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
            background-repeat:     repeat-x;
            background-position:   left top;
            padding-top:           4px;
            color:                 #666;
        }
    </style>
    <script type="text/javascript" language="javascript">
        var hide = null;
        var show = null;
        var children = null;

        function init() {
            /* Search form initialization */
            var form = document.forms['search'];
            if (form != null) {
                form.elements['domains'].value = location.hostname;
                form.elements['sitesearch'].value = location.hostname;
            }

            /* Children initialization */
            hide = document.getElementById('hide');
            show = document.getElementById('show');
            children = document.all != null ?
                    document.all['children'] :
                    document.getElementById('children');
            if (children != null) {
                children.style.display = 'none';
                show.style.display = 'inline';
                hide.style.display = 'none';
            }
        }

        function showChildren() {
            children.style.display = 'block';
            show.style.display = 'none';
            hide.style.display = 'inline';
        }

        function hideChildren() {
            children.style.display = 'none';
            show.style.display = 'inline';
            hide.style.display = 'none';
        }
    </script>
    <title>Template Loading</title>
</head>
<body onload="init()">
<table border="0" cellpadding="2" cellspacing="0" width="100%">
    <tr class="topBar">
        <td align="left" valign="middle" class="topBarDiv" align="left" nowrap>
            &nbsp;<a href="home.html">Home</a>&nbsp;&gt;&nbsp;<a href="guides.html">Guides</a>&nbsp;&gt;&nbsp;<a href="tag-developers-guide.html">Tag Developers Guide</a>&nbsp;&gt;&nbsp;<a href="struts-tags.html">Struts Tags</a>&nbsp;&gt;&nbsp;<a href="ui-tags.html">UI Tags</a>&nbsp;&gt;&nbsp;<a href="themes-and-templates.html">Themes and Templates</a>&nbsp;&gt;&nbsp;<a href="template-loading.html">Template Loading</a>
        </td>
        <td align="right" valign="middle" nowrap>
            <form name="search" action="https://www.google.com/search" method="get">
                <input type="hidden" name="ie" value="UTF-8" />
                <input type="hidden" name="oe" value="UTF-8" />
                <input type="hidden" name="domains" value="" />
                <input type="hidden" name="sitesearch" value="" />
                <input type="text" name="q" maxlength="255" value="" />
                <input type="submit" name="btnG" value="Google Search" />
            </form>
        </td>
    </tr>
</table>

<div id="PageContent">
    <div class="pageheader" style="padding: 6px 0px 0px 0px;">
        <!-- We'll enable this once we figure out how to access (and save) the logo resource -->
        <!--img src="/wiki/images/confluence_logo.gif" style="float: left; margin: 4px 4px 4px 10px;" border="0"-->
        <div style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts 2 Documentation</div>
        <div style="margin: 0px 10px 8px 10px"  class="pagetitle">Template Loading</div>

        <div class="greynavbar" align="right" style="padding: 2px 10px; margin: 0px;">
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=13817">
                <img src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Edit Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=13817">Edit Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">
                <img src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Browse Space"></a>
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">Browse Space</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=13817">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=13817">Add Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=13817">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add News"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=13817">Add News</a>
        </div>
    </div>

    <div class="pagecontent">
        <div class="wiki-content">
            <div id="ConfluenceContent"><p>Templates are loaded first by searching the application and then by searching the classpath. If a template needs to be overridden, an edited copy can be placed in the application, so that is found first.</p>

<div class="confluence-information-macro confluence-information-macro-information"><p class="title">One for all</p><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
<p>FreeMarker is the default templating engine. The FreeMarker templates are used regardless of what format the view may use. Internally, the JSP, FTL, Velocity tags are all rendered using FreeMarker. </p></div></div>

<h2 id="TemplateLoading-TemplateandThemes">Template and Themes</h2>

<p>Templates are loaded based the template directory and theme name (see <a shape="rect" href="selecting-themes.html">Selecting Themes</a>). The template directory is defined by the <code>struts.ui.templateDir</code> property in <a shape="rect" href="strutsproperties.html">struts.properties</a> (defaults to <code>template</code>). If a tag is using the <code>xhtml</code> theme, the following two locations will be searched (in this order):</p>

<div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> In the application </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> <code>/template/xhtml/template.ftl</code> </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> In the classpath   </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> <code>/template/xhtml/template.ftl</code> </p></td></tr></tbody></table></div>


<p><img class="emoticon emoticon-warning" src="https://cwiki.apache.org/confluence/s/en_GB/5982/f2b47fb3d636c8bc9fd0b11c0ec6d0ae18646be7.1/_/images/icons/emoticons/warning.png" data-emoticon-name="warning" alt="(warning)"> For performance reasons, you may want to prefer the first location, although the second one is more flexible. See <a shape="rect" href="performance-tuning.html">Performance Tuning</a> for a discussion on this topic.</p>

<h2 id="TemplateLoading-OverridingTemplates">Overriding Templates</h2>

<p>The default templates provided in the <code>struts-core.jar</code> should suit the needs of many applications. However, if a template needs to be modified, it's easy to plug in a new version. Extract the template you need to change from the <code>struts-core.jar</code>, make the modifications, and save the updated copy to <code>/template/$theme/$template.ftl</code>. If you are using the xhmtl theme and need to change how the select tags render, edit that template and save it to <code>/template/xhtml/select.ftl</code>.</p>

<p><img class="emoticon emoticon-warning" src="https://cwiki.apache.org/confluence/s/en_GB/5982/f2b47fb3d636c8bc9fd0b11c0ec6d0ae18646be7.1/_/images/icons/emoticons/warning.png" data-emoticon-name="warning" alt="(warning)"> It is easier and better to edit and override an existing template than provide a new one of your own.</p>

<h2 id="TemplateLoading-AlteringTemplateLoadingBehaviour">Altering Template Loading Behaviour</h2>

<p>It is possible to load template from other locations, like the file system or a URL. Loading templates from alternate locations can be useful not only for tags, but for custom results. For details, see the <a shape="rect" href="freemarker.html">FreeMarker</a> documentation and consult the section on extending the FreeMarkerManager.</p>

<h2 id="TemplateLoading-AlternativeTemplateEngines">Alternative Template Engines</h2>

<p>The framework provides for template rendering engines other than FreeMarker. (Though, there is rarely a need to use another system!)</p>

<div class="confluence-information-macro confluence-information-macro-warning"><p class="title">Don't try this at home!</p><span class="aui-icon aui-icon-small aui-iconfont-error confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Alternative template engines are best left to advanced users with special needs!</p></div></div>

<p>The framework supports three template engines, which can be controlled by the <code>struts.ui.templateSuffix</code> in <a shape="rect" href="strutsproperties.html">struts.properties</a>.</p>

<div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> ftl (default) </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="freemarker.html">FreeMarker</a>-based template engine </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> vm            </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="velocity.html">Velocity</a>-based template engine   </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> jsp           </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="jsp.html">JSP</a>-based template engine        </p></td></tr></tbody></table></div>


<p>The only set of templates and themes provided in the distribution is for FreeMarker. In order to use another template engine, you must provide your own template and theme for that engine. </p>

<div class="confluence-information-macro confluence-information-macro-tip"><p class="title">Stay the course</p><span class="aui-icon aui-icon-small aui-iconfont-approve confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
<p>Don't feel that you need to rewrite the templates to match your view format. If you need to customize the template, try copying and modifying the FreeMarker template first. Most changes should be obvious.</p></div></div></div>
        </div>

        
    </div>
</div>
<div class="footer">
    Generated by CXF SiteExporter
</div>
</body>
</html>
